<template>
  <el-dialog :visible.sync="show" title="图片上传" width="650px" class="upload-dialog" append-to-body>
    <div class="upload-container">
      <div class="upload-main flex" v-show="files.length === 0">
        <div class="upload-content">
          <i class="el-icon-picture-outline upload-icon"></i>
          <button type="button" class="upload-btn">点击选择图片</button>
          <input type="file" ref="file" class="upload-file" @change="onSelectFile" :multiple="multiple" accept="image/*"/>
        </div>
      </div>

      <template v-if="files.length">
        <div class="upload-header">
          <div class="upload-header-head">
            <span v-show="tip === ''">选中{{ files.length }}张图片，共{{ totalSize | byteConvert }}。</span>

            <span v-show="tip">{{ tip }}</span>
          </div>
          <div class="upload-header-foot">
            <el-button size="small" @click="onAddFile" v-show="multiple">继续添加</el-button>

            <el-button size="small" type="primary" @click="onStart">开始上传</el-button>
          </div>
        </div>

        <div class="upload-hei">
          <vue-scroll>
            <ul class="upload-files">
              <li v-for="(file, fileIndex) in files" :key="fileIndex">
                <img class="thumb" :src="getFile(file)"/>

                <div class="upload-files-action">
                  <span class="upload-icon el-icon-delete" title="删除" @click="onRemoveFile(fileIndex)"></span>
                </div>

                <div class="upload-files-progress" v-if="!file.success">
                  <span class="tip" v-show="file.error">{{ file.error }}</span>

                  <el-progress :show-text="false" :percentage="file.progress" v-show="file.progress"></el-progress>
                </div>

                <div class="success" v-if="file.success">
                </div>
              </li>

              <li class="select" v-show="multiple">
                <input type="file" ref="add-file" class="upload-files-item" :multiple="multiple" accept="image/*" @change="onSelectFile"/>
              </li>
            </ul>
          </vue-scroll>
        </div>
      </template>
    </div>

    <div slot="footer">
      <el-button @click="onConfirm">确认</el-button>
      <el-button @click="show = false">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'KDialogUpload',
  props: {
    value: Boolean,
    multiple: Boolean
  },
  computed: {
    show: {
      get () {
        return this.value
      },
      set (v) {
        this.$emit('input', v)
      }
    },
    totalSize () {
      let size = 0
      this.files.map(file => {
        size += file.data.size
      })
      return size
    }
  },
  watch: {
    value (v) {
      if (!v) {
        this.files = []
        this.tip = ''
      }
    }
  },
  data () {
    return {
      files: [],
      tip: ''
    }
  },
  methods: {
    onOpenFile (idx) {
      this.$refs['file'].click()
    },
    onAddFile () {
      this.$refs['add-file'].click()
    },
    // 选择文件
    onSelectFile (evt) {
      for (let i = 0; i < evt.target.files.length; i++) {
        this.files.push({
          data: evt.target.files[i],
          success: false,
          progress: 0
        })
      }
    },
    // 删除文件
    onRemoveFile (idx) {
      this.files.splice(idx, 1)
    },
    // 获取图片数据
    getFile (file) {
      return window.URL.createObjectURL(file.data)
    },
    // 开始上传
    onStart () {
      this.files.map(file => {
        file.error = null
        if (file.success) {
          return
        }
        const fd = new FormData()
        fd.append('file', file.data)
        this.$http.post('admin/upload/image', fd, {
          headers: {'Content-Type':'multipart/form-data'},
          onUploadProgress: (progressEvent) => {
            file.progress = (progressEvent.loaded / progressEvent.total * 100 | 0)
          },
          autoResponse: false
        })
          .then(result => {
            if (result.res_code === 0) {
              file.url = result.url
              file.success = true
              file.error = null
            } else {
              file.error = result.res_msg
              file.progress = 0
            }
          })
          .catch(err => {
            if (err?.response?.data?.res_msg) {
              file.error = err.response.data.res_msg
            } else {
              file.error = err.message
            }
            file.progress = 0
            console.error(file.error)
          })
      })
    },
    // 确认
    onConfirm () {
      const count = this.files.filter(item => !item.success).length
      if (count) {
        this.tip = `还有${this.files.length - count}个文件未上传`
        return
      }
      this.$emit('success', this.files.map(file => {
        return {
          url: file.url,
          name: file.data.name
        }
      }))
      this.show = false
    }
  }
}
</script>

<style scoped lang="scss">
  .upload-dialog {
    /deep/ {
      .el-dialog__body {
        padding: 0;
        margin: 0 10px;
      }
    }
  }
  .upload-main {
    height: 280px;
    border: dotted 2px #ddd;
    border-radius: 4px;
  }
  .upload-header {
    margin: 10px 0;
    padding: 0 10px;
    display: flex;
    align-items: center;
    &-head {
      flex: 1;
    }
    &-foot {
      flex: 1;
      text-align: right;
    }
  }
  .upload-content {
    margin: 0 auto;
    text-align: center;
    position: relative;
    .upload-icon {
      color: #E1E1E1;
      font-size: 50px;
      margin: 20px 0;
    }
    .upload-file {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      opacity: 0;
      z-index: 0;
    }
  }
  .flex {
    display: flex;
    align-items: center;
  }
  .upload-btn {
    background-color: #399EE4;
    color: #fff;
    border: none;
    padding: 10px 50px;
    border-radius: 4px;
    font-size: 18px;
    display: block;
    cursor: pointer;
    z-index: 1;
    &:hover {
      background-color: #4FA9E7;
      cursor: pointer;
    }
  }
  .upload-hei {
    height: 300px;
  }
  .upload-files {
    .thumb {
      width: 100%;
      height: 100%;
    }
    li {
      width: 113px;
      height: 113px;
      display: inline-block;
      border: 1px solid #eeeeee;
      border-radius: 0;
      position: relative;
      overflow: hidden;
      margin: 0 5px;
      .upload-files-item {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        opacity: 0;
        cursor: pointer;
      }
      &:hover {
        .upload-files-action {
          transform: translateY(30px);
        }
      }
    }
    li.select {
      width: 113px;
      height: 113px;
      display: inline-block;
      background: url(./images/image.png) no-repeat center 12px;
      border: 1px solid #eeeeee;
      border-radius: 0;
      position: relative;
      overflow: hidden;
    }
    &-action {
      position: absolute;
      top: -30px;
      left: 0;
      right: 0;
      background: rgba(0, 0, 0, 0.65);
      text-align: right;
      color: #fff;
      transition: all .6s;
      overflow: hidden;
      .upload-icon {
        transition: all .4s;
        cursor: pointer;
        padding: 5px;
        &:hover {
          color: #ff2878;
        }
      }
    }
    .success {
      display: block;
      position: absolute;
      left: 0;
      bottom: 0;
      height: 40px;
      width: 100%;
      z-index: 200;
      background: url(./images/success.png) no-repeat right bottom;
    }
    &-progress {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      .tip {
        display: block;
        color: #fff;
        background: #ff1c26;
        font-size: 12px;
        width: 100%;
      }
      /deep/ {
        .el-progress, .el-progress-bar, .el-progress-bar__outer {
          height: 10px !important;
        }
      }
    }
  }
</style>
